//    Copyright (C) Kherty.  All rights reserved.
using System;

namespace OpenLS.Spreadsheet.Parsing
{
    class LexerCreators
    {
        [ThreadStatic]protected static TokenCreator[][] _creators;
        // char -> TokenCreator[]
        static void addMCSymbol(MCSymbol s)
        {
            addTokenCreator(new MCSymbolCreator(s));
        }
        static void addSymbol(Symbol s)
        {
            addTokenCreator(new SymbolCreator(s));
        }
        static void addKeywords()
        {
            addKeyword(new True());
        }
        static void addKeyword(Keyword k)
        {
            addTokenCreator(new KeywordCreator(k));
        }
        static void addTokenCreator(TokenCreator c)
        {
            char[] firstChars = c.FirstChars();
            for (int i = 0; i < firstChars.Length; i++)
            {
                int j = firstChars[i];
                TokenCreator[] l = _creators[j];
                if (l == null)
                {
                    _creators[j] = new TokenCreator[] { c };
                }
                else
                {
                    var nc = new TokenCreator[l.Length + 1];
                    Array.Copy(l, 0, nc, 0, l.Length);
                    //l.CopyTo(nc, 0);
                    nc[nc.Length - 1] = c;
                    _creators[j] = nc;
                }
                //l.Add(c);
            }
        }

        protected static void Build()
        {
            if (_creators != null)
                return;
            _creators = new TokenCreator[256][];
            addKeywords();
            addTokenCreator(new SpaceProcessor());
            addTokenCreator(new ExplicitStringCreator());
            addTokenCreator(new ExplicitCharacterCreator());
            addTokenCreator(new IdentifierCreator());
            //addTokenCreator(new ReferenceCreator());
            addTokenCreator(new NumericCreator());
            addSymbols();
            //throw new NotImplementedException();
        }
        static void addSymbols()
        {
            addMCSymbol(new Inequality());
            addMCSymbol(new GreaterThanOrEqual());
            addMCSymbol(new LessThanOrEqual());
            addSymbol(new Equality());
            addSymbol(new Addition());
            addSymbol(new Power());
            addSymbol(new Concatenate());
            addSymbol(new Colon());
            addSymbol(new Subtraction());
            addSymbol(new Multiply());
            addSymbol(new Division());
            addSymbol(new Percent());
            addSymbol(new GreaterThan());
            addSymbol(new LessThan());
            addSymbol(new LeftSquareBracket());
            addSymbol(new RightSquareBracket());
            addSymbol(new LeftCurlyBracket());
            addSymbol(new RightCurlyBracket());
            addSymbol(new LeftParenthesis());
            addSymbol(new RightParenthesis());
            //\\addSymbol(new Colon());
            addSymbol(new Exclamation());
            addSymbol(new SemiColon());
            addSymbol(new Coma());
            addSymbol(new Dollar());
        }

    }
}
